import { Router } from 'vue-router'
import { useUserStore } from '@/store/modules/user'
import { fetchProductByCode, fetchSystemInfo, fetchTenantByCode } from "@/apis/sys/user";
import { localSave, localGet, getStorageByKey, localGetApplicationId } from "@/utils/common";
import { useSystemStore } from '@/store/modules/system'
import { getApplicationInfo } from '@/apis/sys/application'
import { getAppBaseUrl } from '@/utils/index'
import { ROUTER_NAME } from '@/constant'

export function createSiteInfoGuard(router: Router) {
  const microAppData = window.microApp ?? window.eventCenterForViteApp
  if (microAppData || window.__MICRO_APP_ENVIRONMENT__) {
    return;
  }
  const userStore = useUserStore()
  const systemStore = useSystemStore()
  router.beforeEach(async (to) => {
    return new Promise((resolve) => {
      // 加载租户信息等
      let codeBase = userStore;
      if (!codeBase.productCode && !codeBase.tenantCode) {
        codeBase = to.params;
      }

      let { productCode, tenantCode } = codeBase || {};

      const microAppData = window.microApp?.getData() ?? window.eventCenterForViteApp?.getData();
      let isOnlyMicroApp = false;

      const _systemStore = localGetApplicationId("app-user-store") || getStorageByKey("app-user-store");

      if (
          !productCode &&
          !tenantCode &&
          _systemStore &&
          _systemStore.productId &&
          _systemStore.tenantId &&
          _systemStore.token &&
          _systemStore.uuid
      ) {
        resolve(true);
        return;
      }

      // 如果是微前端嵌入当前页面，判断父应用是否是二级域名模式
      if (microAppData && !productCode && !tenantCode) {
        isOnlyMicroApp = true;
        const { pathname } = window.location;
        // 如果父级是二级域名模式，使用父级二级域名的code
        const [, _productCode, _tenantCode] = pathname.split("/");
        _productCode.startsWith("prd") && (productCode = _productCode);
        _tenantCode.startsWith("tnt") && (tenantCode = _tenantCode);
      }

      let getProductInfoApi;

      if (!productCode || !tenantCode) {
        // 加载租户信息等
        let host = window.location.hostname;
        if (import.meta.env.DEV) {
          // 开发环境使用配置的域名获取应用信息
          host = import.meta.env.VITE_DEV_PRODUCT_DOMAIN ?? host;
        } else {
          host = host + (window.location.port === "" ? "" : ":" + window.location.port);
        }
        host = host + import.meta.env.VITE_PUBLIC_PATH + "/";

        getProductInfoApi = fetchSystemInfo(host);
      } else {
        getProductInfoApi = Promise.allSettled([fetchProductByCode(productCode), fetchTenantByCode(tenantCode)]).then(results => {
          const [{ value: productDetailResp }, { value: tenantDetailResp }] = results;
          return { data: { ...productDetailResp?.data, tenantId: tenantDetailResp?.data?.id }};
        });
        // 如果是从父级来的code，不存储
        if (!isOnlyMicroApp) {
          userStore.productCode = productCode;
          userStore.tenantCode = tenantCode;
        }
      }

      getProductInfoApi
        .then(resp => resp.data)
        .then(resp => {
          const { id, name, showName, url, extSetting, tenantId } = resp
          // 如果地址中的租户发生变化，需要重新登录
          if(tenantId && userStore.tenantId && String(tenantId) !== String(userStore.tenantId) && ![ROUTER_NAME.PAGE_LOGIN, ROUTER_NAME.AUTH_LOGIN].includes(to.name)) {
            userStore.logout()
            return
          }
          userStore.tenantId = tenantId
          userStore.productId = id
          // 模拟使用的是Product Container进行的登录
          userStore.appid = 'product-container'
          const { fullPath } = to
          const applicationId = fullPath.match(/app_(\d+)/)?.[1]
          const appUserStore: any = localGet(`app_${applicationId}`)
          if (appUserStore && 'app-user-store' in appUserStore) {
            appUserStore['app-user-store']['tenantId'] = tenantId
            appUserStore['app-user-store']['productId'] = id
            appUserStore['app-user-store']['appid'] = 'product-container'
            localSave(`app_${applicationId}`, appUserStore)
          }
          // 兼容DG等项目在localStorage中读取产品信息的场景
          localSave('al__ALL_PRODUCT_INFO', { id, name, showName, url, extSetting, tenantId })
          localSave('al__PRODUCT_CONTAINER_ID', id)
          localSave('al__APPID', 'product-container')
        }).catch(e => {
        // do nothing
      }).finally(() => {
        resolve(true)
      })
        .then(() => {
          const { fullPath } = to
          const applicationId = fullPath.match(/app_(\d+)/)?.[1]
          if (!applicationId) {
            return
          }
          getApplicationInfo(applicationId)
            .then(resp => {
              const { h5ProductExists } = resp
              const appBaseUrl = getAppBaseUrl()
              const h5Url = h5ProductExists ? `${location.origin}${appBaseUrl}/h5_${applicationId}/` : '';
              systemStore.updateH5ProductUrl(h5Url)
            })
            .catch(() => {
              systemStore.updateH5ProductUrl('')
            })
        })
    })
  })
}
